<?php
//$Id: File.php 590 2012-12-12 07:27:11Z tomqin@gmail.com $

/**
 * Part of the framework.
 *
 * @package     Library
 * @version     1.0
 * @copyright   Copyright (C) 2010-2012 SupeFun.com Inc.
 * @author      TomQin <tomqin@gmail.com>
 * @license     http://www.supefun.com/license/
 */

class File
{

    /**
     * Get the contents of a file.
     *
     * @param  string   file name
     * @return string   file content
     */
    public static function read($file) {
        return file_get_contents($file);
    }

    /**
     * Write to a file.
     *
     * @param  string   file name
     * @param  string   file content
     * @return int
     */
    public static function write($file, $data) {
        return file_put_contents($file, $data, LOCK_EX);
    }

    /**
     * Append to a file.
     *
     * @param  string   file name
     * @param  string   file content
     * @return int
     */
    public static function append($file, $data) {
        return file_put_contents($file, $data, LOCK_EX | FILE_APPEND);
    }

    /**
     * Transformation "\" to "/" of a path or file name.
     *
     * @param string    file name
     * @return string   transformated file name
     */
    public static function path($path) {
        $path = str_replace('\\', '/', $path);
        if (substr($path, -1) != '/') $path = $path.'/';
        return $path;
    }

    /**
     * Create a new dir
     *
     * @param string    路径
     * @param string    模式
     * @return string
     */
    public static function mkdir($path, $mode = 0777) {
        if (is_dir($path)) return true;
        if (is_file($path) && !unlink($path)){
            return false;
        }

        $path = self::path($path);
        mkdir($path, $mode, true);
        return is_dir($path);
    }

    /**
     * 拷贝目录及下面所有文件
     *
     * @param string    原路径
     * @param string    目标路径
     * @return string   如果目标路径不存在则返回false，否则为true
     */
    public static function dircopy($fromdir, $todir) {
        $fromdir = self::path($fromdir);
        $todir   = self::path($todir);

        if (!is_dir($fromdir))
            return false;

        if (!is_dir($todir))
            self::mkdir($todir, 0777);

        $list = glob($fromdir.'*');
        if (!empty($list)) {
            foreach ($list as $v) {
                $path = $todir.basename($v);
                if (is_dir($v)) {
                    self::copy($v, $path);
                } else {
                    copy($v, $path);
                    chmod($path, 0777);
                }
            }
        }
        return true;
    }

      /**
       *
       *  Renames the source file to the target file. If the target already exists, you can switch
       *  $force to true. This indicates, that the target file will be overwritten.
       *
       *  @param string $sourceFile the source file path
       *  @param string $targetFile the target file path
       *  @param bool $force true = overwrite, false = return error
       *  @return bool $status status code (true = ok, false = error)
       *
       *  @author Christian Achatz
       *  @version
       */
      public static function rename($sourceFile ,$targetFile, $force = false) {

         // create realpath from the source and target file
         $source = str_replace('\\','/',realpath($sourceFile));
         $target = str_replace('\\','/',$targetFile);
         if (!file_exists($source)) {
            trigger_error('[File::renameFile()] The source file "'.$sourceFile.'" does not exist!',E_USER_NOTICE);
            return false;
         }

         // copy source to target
         if ((file_exists($target) && $force === true) || !file_exists($target)) {
            if (rename($source, $target)) {
               return true;
            } else {
               return false;
            }
         } else {
            return false;
         }
      }

    /**
     * 转换目录下面的所有文件编码格式
     *
     * @param string    原字符集
     * @param string    目标字符集
     * @param string    目录地址
     * @param string    转换的文件格式
     * @return string   如果原字符集和目标字符集相同则返回false，否则为true
     */
    public static function iconv($in_charset, $out_charset, $dir, $fileexts = 'php|html|htm|shtml|shtm|js|txt|xml') {
        if ($in_charset == $out_charset) return false;
        $list = dir_list($dir);
        foreach ($list as $v) {
            if (preg_match("/\.($fileexts)/i", $v) && is_file($v)) {
                file_put_contents($v, iconv($in_charset, $out_charset, file_get_contents($v)));
            }
        }
        return true;
    }

    /**
     * 列出目录下所有文件
     *
     * @param string    路径
     * @param string    扩展名
     * @param array     增加的文件列表
     * @return array    所有满足条件的文件
     */
    public static function glob($path, $exts = '', $list= array()) {
        $path = self::path($path);
        $files = glob($path.'*');
        foreach ($files as $v) {
            $fileext = fileext($v);
            if (!$exts || preg_match("/\.($exts)/i", $v)) {
                $list[] = $v;
                if (is_dir($v)) {
                    $list += self::glob($v, $exts, $list);
                }
            }
        }
        return $list;
    }

    /**
     * 设置目录下面的所有文件的访问和修改时间
     *
     * @param string    路径
     * @param integer   修改时间
     * @param integer   访问时间
     * @return array    不是目录时返回false，否则返回 true
     */
    public static function touch($path, $mtime = TIMESTAMP, $atime = TIMESTAMP) {
        if (!is_dir($path)) return false;
        $path = self::path($path);
        if (!is_dir($path)) touch($path, $mtime, $atime);
        $files = glob($path.'*');
        foreach ($files as $v) {
            is_dir($v) ? self::touch($v, $mtime, $atime) : touch($v, $mtime, $atime);
        }
        return true;
    }

    /**
     * 目录列表
     *
     * @param string    路径
     * @param integer   父 id
     * @param array     传入的目录
     * @return array    返回目录列表
     */
    public static function tree($dir, $parentid = 0, $dirs = array()) {
        global $id;
        if ($parentid == 0) $id = 0;
        $list = glob($dir.'*');
        foreach ($list as $v) {
            if (is_dir($v)) {
                $id++;
                $dirs[$id] = array(
                    'id'  =>$id,
                    'pid' =>$parentid,
                    'name'=>basename($v),
                    'dir' =>self::path($v)
                );
                $dirs = self::tree($v.'/', $id, $dirs);
            }
        }
        return $dirs;
    }

    /**
     * 删除目录及目录下面的所有文件
     *
     * @param string    路径
     * @return boolean  如果成功则返回 TRUE，失败则返回 FALSE
     */
    public static function delete($dir) {
        $dir = self::path($dir);
        if (!is_dir($dir)) return false;
        $list = glob($dir.'*');
        foreach ($list as $v) {
            is_dir($v) ? self::delete($v) : unlink($v);
        }
        return rmdir($dir);
    }

    /**
     * 文件下载
     *
     * @param string    文件路径
     * @param string    文件名称
     * @return void
     */
    function download($filepath, $filename = '') {
        //判断是否为 IE 浏览器
        $IE = false;
        $useragent = strtolower($_SERVER['HTTP_USER_AGENT']);
        if ((strpos($useragent, 'opera') !== false) || (strpos($useragent, 'konqueror') !== false)) $IE = false;
        if (strpos($useragent, 'msie ') !== false) $IE = true;

        if (!$filename) $filename = basename($filepath);
        if ($IE) $filename = rawurlencode($filename);
        $filetype = fileext($filename);
        $filesize = sprintf("%u", filesize($filepath));
        if (ob_get_length() !== false) @ob_end_clean();

        header('Pragma: public');
        header('Last-Modified: '.gmdate('D, d M Y H:i:s') . ' GMT');
        header('Cache-Control: no-store, no-cache, must-revalidate');
        header('Cache-Control: pre-check=0, post-check=0, max-age=0');
        header('Content-Transfer-Encoding: binary');
        header('Content-Encoding: none');
        header('Content-type: '.$filetype);
        header('Content-Disposition: attachment; filename="'.$filename.'"');
        header('Content-length: '.$filesize);
        readfile($filepath);
        exit;
    }
}
?>